package main

import (
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"strconv"
	"time"
)

// 产生指定长度的随机字符串
func generateRandomStr(n int) string {
	var strarr  = [62]string{}
	result := ""

	// 填充 0 到 9
	for i:=0; i < 10; i++ {
		strarr[i] = strconv.Itoa(i)
	}

	// 填充 a 到 z
	for i := 0; i < 26; i++ {
		strarr[i + 10] = string(i+97)
	}

	// 填充 A 到 Z
	for i := 0; i < 26; i++ {
		strarr[36+i] = string(i + 65)
	}

	source := rand.NewSource(time.Now().Unix())
	r := rand.New(source)
	for i := 0; i < n; i++ {
		index := r.Intn(len(strarr))
		result = result + strarr[index]
	}

	return result
}

var sessions map[string]string

func writeSessionID(w http.ResponseWriter)  {
	sessionId := generateRandomStr(20)
	sessions[sessionId] = generateRandomStr(100)
	expiration := time.Now()
	expiration = expiration.AddDate(0,0,40)
	cookie := http.Cookie{Name:"mysession_id",Value:sessionId,Expires:expiration}
	http.SetCookie(w,&cookie)
}

func mysession(w http.ResponseWriter, r *http.Request)  {
	cookie,err := r.Cookie("mysession_id")

	// 该用户已经提交了 sessionID
	if err == nil {
		// 校验 SessionID
		data,exist := sessions[cookie.Value]

		// 服务端存在这个 SessionID，说明用户不是第一次访问服务端
		if exist {
			fmt.Fprint(w,"该用户已经访问过服务器了：" + data)
		} else {
			// 需要重新产生 SessionID
			writeSessionID(w)
			fmt.Fprint(w,"该用户第一次访问服务器")
		}
	} else {
		// 需要重新生产 SessionID
		writeSessionID(w)
		fmt.Fprint(w,"该用户第一次访问服务器")
	}
}

func main()  {
	sessions = make(map[string]string)
	http.HandleFunc("/",mysession)

	fmt.Println("服务器已经启动，请在浏览器地址栏中输入：http://localhost:9090")

	// 启动 HTTP 服务，并监听端口号，开始监听，处理请求，返回响应
	err := http.ListenAndServe(":9090", nil)
	if err != nil {
		log.Fatal("ListenAndServe",err)
	}
}
